﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Av.Utils;
using System.Diagnostics;

namespace WebUtils
{

    public class SearchPosition
    {
        public int Total { get; set; }

        public int Postion { get; set; }

        public int Page { get{ return 0; } }

        public string Keyword { get; set; }

        public string SearchedDomain { get; set; }
    }

    public class SearchItem
    {
        public int Position { get; set; }

        public string Url { get; set; }

        public string Title { get; set; }

        public string Text { get; set; }
    }

    public class SearchResultPage
    {
        public SearchItem[] Results { get; set; }

        /// <summary>
        /// Gets/sets nr of page, 1-based
        /// </summary>
        public int PageNr { get; set; }

        public bool ContainsDomain(string p)
        {
            Log4cs.Log("Searching for [{0}]", p);
            for(int i = 0; (Results != null) && (i < Results.Length); i++)
            {
                Log4cs.Log("  {0}", Results[i].Url);
                if( Results[i].Url.Contains(p) )
                {
                    return true;
                }
            }

            return false;
        }
    }

    public class GoogleResultParser
    {

        /// <summary>
        /// Parses string (Google page result) and returns
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static SearchResultPage Parse(string s)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            SearchResultPage p = new SearchResultPage();
            List<SearchItem> items = new List<SearchItem>();

            int pos = 0;
            string resultStats = GetResultStats(s, ref pos);
            //Log4cs.Log(Importance.Debug, "Results found: {0}", resultStats);

            string liCssClass = "g";

            Regex rx = null;
            
            // List all <li> which have class name
            rx = new Regex(@"(<li)([\s\w]+)(class)([\s]*)(=)([\s]*)(""?)([\w\d]+)");
            Match m = rx.Match(s, pos);
            
            int searchItemStart = pos;
            while( m.Success )
            {
                //Log4cs.Log(Importance.Debug, "Found <li>...");
                if(m.Groups[8].Value.Equals(liCssClass))
                {
                    //Log4cs.Log(Importance.Debug, "<li> contains Google search item");
                    SearchItem si = ParseItem(s.Substring(m.Index, 500));
                    if(!string.IsNullOrEmpty(si.Url))
                    {
                        items.Add(si);
                    }
                } else
                {
                    //Log4cs.Log("<li> with CSS class name '{0}' is ignored!", m.Groups[9].Value);
                }
                m = m.NextMatch();
                pos += m.Length;
            }

            p.Results = items.Count > 0 ? items.ToArray() : null;

            sw.Stop();
            Log4cs.Log("Parsed page in {0} ms...", sw.ElapsedMilliseconds);
            Log4cs.Log("Result stats from Google: {0}", resultStats);

            return p;
        }

        private static SearchItem ParseItem(string s)
        {
            Log4cs.Log(Importance.Debug, "Search item is here: {0}", s);
            SearchItem si = new SearchItem();
            Regex rx = new Regex(@"(<h3)([\s\w\w]+)(class)([\s]*)(""?)(=)([\s]*)(""?)([\w\d]+)");
            Match m = rx.Match(s);

            if(m.Success )
            {

                if(m.Groups[9].Value.Equals("r"))
                {
                    //Log4cs.Log(Importance.Debug, "Searching for URL in: {0}", s);
                    Regex rxUrl = new Regex(@"(<a )([^""]+)("")([^""]+)");
                    Match mUrl = rxUrl.Match(s);
                    if(mUrl.Success)
                    {
                        //Log4cs.Log("Got URL in search item: {0}", mUrl.Groups[4].Value);
                        si.Url = mUrl.Groups[4].Value;
                    }
                } else
                {
                    //Log4cs.Log("<H3> does not contain CSS class 'r'!");
                }
            }

            return si;
        }

        /// <summary>
        /// Returns string containing how many results were found
        /// </summary>
        /// <param name="s">String to search</param>
        /// <param name="pos">Position in string, which will be changed</param>
        protected static string GetResultStats(string s, ref int pos)
        {
            Regex rx = new Regex("(id)(\\s*)(=)(\\s*)(\"?)(resultStats)(\"?)(>)([^<]+)");
            Match m = rx.Match(s, pos);

            pos = pos + m.Length;

            return m.Success ? m.Groups[9].Value : "N/A";
        }

    }
}
